from ultralytics.engine.results import Results
import serial


class TransBelt():
    def __init__(self, number: int = 8, width: int = 20):
        self.the_border_to_jugde_drop = 10
        self.first_belt_y = 20
        self.belt_width = width
        self.last_belt_y = 180
        self.something_dropped = -1
        # 这里需要设置串口路径和波特率
        self.uart = serial.Serial("path/to/uart", 115200)
        self.uart.open()

    def run(self, items: Results):
        the_one = self.find_the_one_near_to_edge(items)
        if the_one is not None:
            belts_to_move = self.choose_belts_to_move(the_one)
            self.send_strategy(belts_to_move)

    def find_the_one_near_to_edge(self, items: Results) -> dict | None:
        # 单次识别的所有物体的中心位置(x,y) 宽高(w,h)
        tmp = 0
        the_one = None
        for item in items.summary():
            # class_id = item['class']
            # class_name = item['name']
            # conf = item['confidence']
            # box = item['box']
            x1 = item['box']['x1']
            x2 = item['box']['x2']
            center = (x1 + x2) / 2
            if (center > tmp):
                tmp = center
                the_one = item
        if the_one is not None:
            if (tmp > self.the_border_to_jugde_drop):
                self.something_dropped = the_one['class']
        return the_one

    def choose_belts_to_move(self, the_one: dict) -> list[int]:
        x1, y1 = the_one['x1'], the_one['y1']
        x2, y2 = the_one['x2'], the_one['y2']
        current_y = self.first_belt_y
        res = [-1, -1]
        idx = 1
        while (True):
            tmp = current_y + self.belt_width
            if (res[0] != -1 and res[1] != -1):
                break
            if (res[0] == -1):
                if (y1 > tmp):
                    current_y = tmp
                else:
                    res[0] = idx
            if (res[1] == -1):
                if (y2 > tmp):
                    current_y = tmp
                else:
                    res[1] = idx
            idx += 1
        return res

    def send_strategy(self, belts_id: list[int]):
        # 每一段信息以0xa5开头，中间8个数字
        cont = b'\xa5'
        idx = [0, 0, 0, 0, 0, 0, 0, 0]
        for i in belts_id:
            idx[i - 1] = 1
        cont += bytes(idx)
        self.uart.write(cont)

    def is_there_anything_dropped(self) -> int:
        return self.something_dropped

    def reset_drop_judge(self):
        self.something_dropped = -1

    def wait_post_process(self):
        # 等待称重传感器信号
        #
        # 重置信号
        self.something_dropped = -1
